package com.lcifn.middleware.rpc.transport.coder;

import com.lcifn.middleware.rpc.transport.command.Command;
import com.lcifn.middleware.rpc.transport.command.Header;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.List;

/**
 * Command解码
 * @author lichao
 * @date 2021/2/1 16:07
 */
public abstract class CommandDecoder extends ByteToMessageDecoder {

    public static final int LENGTH_FIELD_LENGTH = Integer.BYTES;

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> out) throws Exception {
        if (!byteBuf.isReadable(LENGTH_FIELD_LENGTH)) {
            return;
        }

        // 长度校验
        byteBuf.markReaderIndex();
        int length = byteBuf.readInt() - LENGTH_FIELD_LENGTH;
        if (byteBuf.readableBytes() < length) {
            byteBuf.resetReaderIndex();
            return;
        }

        // Header解码
        Header header = decodeHeader(byteBuf);

        // Payload解码
        int payloadLength = length - header.length();
        byte[] payload = new byte[payloadLength];
        byteBuf.readBytes(payload);

        out.add(new Command(header, payload));
    }

    /**
     * Header解码
     * @param byteBuf
     * @return
     */
    protected Header decodeHeader(ByteBuf byteBuf) {
        // requestId, type, version
        return new Header(byteBuf.readInt(), byteBuf.readInt(), byteBuf.readInt());
    }
}
